package pl.prv.polanie.client.widgets;

import java.util.ArrayList;
import java.util.List;

import pl.prv.polanie.client.Planner;
import pl.prv.polanie.client.widgets.util.GUIUtil;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.EventPreview;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

/**
 * TODO dorobic blokade zamykania okna z opcjami po resizowaniu w IE
 * @author Janusz Prokulewicz
 * Created: 2008-02-05
 */

public class LabelUTextBox extends Composite {
	
	private static final String STYLE_ONFOCUS = "plan-labelUTextBox-onFocus";
	private static final String STYLE_ONLOSTFOCUS = "plan-labelUTextBox-onLostFocus";
	
	private static final String STYLE_ITEMSLIST = "plan-ListBox-itemsList";
	private static final String STYLE_ITEMSLISTSP = "plan-ListBox-itemsListSP";
	private static final String STYLE_ITEMSLISTAP = "plan-ListBox-itemsListAP";
	
	private static final String STYLE_TOPHTML = "plan-ListBox-topHTML";
	private static final String STYLE_BOTTOMHTML = "plan-ListBox-bottomHTML";

	private static final String STYLE_ITEMSLIST_SELECTED = "selected";
	private static final String STYLE_ITEMSLIST_HOVER = "hover";

	AbsolutePanel itemsPanelVP = new AbsolutePanel();
	
	HTML topHTML = null;
	HTML bottomHTML = null;
	
	ScrollPanel itemsSP = new ScrollPanel();
	AbsolutePanel itemsAP = new AbsolutePanel();
	
	private int itemsPanelMinWidth = 150;
	private int itemsPanelMinHeight = 29;
	
	private int itemsPanelHeight = 100;
	
	int selectedItemindex = 0;
	
	EventPreview activeEP = null;
	EventPreview resizeEP = null;
	
//	List htmls = new ArrayList();
	private TextBox textBox = new TextBox();
	
	List items = new ArrayList();
	List values = new ArrayList();
	
	private boolean resizingItemsPanelInProgress = false;
	
	
	public LabelUTextBox() {
		textBox.setReadOnly(true);
		textBox.setStyleName(STYLE_ONLOSTFOCUS);
		
		textBox.addFocusListener(new FocusListener() {
			public void onFocus(Widget sender) {
				setViewOnFocus();
			}
			public void onLostFocus(Widget sender) {
				setViewOnLostFocus();
			}
		});
		initWidget(textBox);
		
		setupActiveEP();
		
		
		
		topHTML = new HTML("Academic Title");
		topHTML.setStyleName(STYLE_TOPHTML);


		itemsAP.setWidth("300px");
		itemsAP.setStyleName(STYLE_ITEMSLISTAP);
	
		
		itemsSP.setStyleName(STYLE_ITEMSLISTSP);
		DOM.setStyleAttribute(itemsSP.getElement(), "overflowX", "hidden");
		itemsSP.setPixelSize(200, 100);
		itemsSP.add(itemsAP);
		

		
		
		bottomHTML = new HTML("<div class='resizeHandler'></div>");
		bottomHTML.setStyleName(STYLE_BOTTOMHTML);
		final Element el = DOM.getChild(bottomHTML.getElement(), 0);

		
		//na DOWN ma 
		
		
		DOM.sinkEvents(el, Event.ONMOUSEDOWN);
		DOM.setEventListener(el, new EventListener(){
//			int startx = 0;
//			int starty = 0;
			
			public void onBrowserEvent(Event event) {
//				Widgets.log("event");
				
//			    startx = DOM.eventGetClientX(event)
//		        	- DOM.getAbsoluteLeft(el)
//		        	+ DOM.getElementPropertyInt(el, "scrollLeft")
//		        	+ Window.getScrollLeft();
//			    starty = DOM.eventGetClientY(event)
//		        	- DOM.getAbsoluteTop(el)
//		        	+ DOM.getElementPropertyInt(el, "scrollTop")
//		        	+ Window.getScrollTop();
//				
//			    Widgets.log("x " + startx + ", y " + starty);
				
				if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
					DOM.addEventPreview(new EventPreview () {
						public boolean onEventPreview(Event event) {
							if (DOM.eventGetType(event) == Event.ONMOUSEMOVE) {
								int w = DOM.eventGetClientX(event) - RootPanel.get().getWidgetLeft(itemsPanelVP) + 17;
								int h = DOM.eventGetClientY(event) - RootPanel.get().getWidgetTop(itemsPanelVP) + 17;
								
								// Widgets.log("resize w: " + w + ", h: " + h);
//								Widgets.log("vp " + itemsVP.getOffsetHeight());
								setItemsPanelWidth(w);
								itemsPanelHeight = h;
								setItemsPanelHeightImpl(h);
								//resize 
								return false;
							} else if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
//								if (!GUIUtil.eventOverWiget(itemsPanelVP, event)) {
//									return false;
//								}
								DOM.removeEventPreview(this);
								DOM.eventCancelBubble(event, true);
								
								
								setViewOnLostFocus();
								return false;
							}
							return false;
						};
					});
				}

			}
		});
		
		
		itemsPanelVP.setStyleName(STYLE_ITEMSLIST);
		itemsPanelVP.add(topHTML);
		itemsPanelVP.add(itemsSP, 0, 17);
		itemsPanelVP.add(bottomHTML);
		
		//itemsPanelVP.setPixelSize(300, 200);
		
		setItemsPanelWidth(300);
		
		
		
		textBox.addClickListener(new ClickListener(){
			public void onClick(Widget sender) {
				turnOnItemsPanel();
			}
		});
	}
	
	
	private void setupActiveEP() {
		activeEP = new EventPreview(){
			public boolean onEventPreview(Event event) {
				//obsluga wylaczenia kontrolki
				if (DOM.eventGetType(event)==Event.ONCLICK && !GUIUtil.eventOverWiget(itemsPanelVP, event)) {
					turnOffItemsPanel();
					return false;
				}
				return true;
			}
		};
		
	}
	private void setViewOnFocus(){
		textBox.addStyleName(STYLE_ONFOCUS);
	}
	
	/**
	 * Usuwa styl kontrolki wskazujacy na posiadanie focusu.
	 */
	private void setViewOnLostFocus(){
		textBox.removeStyleName(STYLE_ONFOCUS);
	}
	
	
	LabelUTextBox getInstance() {
		return this;
	}
	
	
	private void turnOnItemsPanel() {
		for (int i = 0; i < items.size(); i++) {
			addItemHTML((String)items.get(i), i == selectedItemindex);	
		}
		
		if (items.size()<=0) {
			addUnselectableItemHTML("no items");
		}
			
		
		DOM.addEventPreview(activeEP);

		RootPanel.get().add(itemsPanelVP, getInstance().getAbsoluteLeft(),
				getInstance().getAbsoluteTop()+getInstance().getOffsetHeight());
		setItemsPanelHeightImpl(itemsPanelHeight);
		
		
		//
		Planner.disableSelection(itemsPanelVP.getElement());
	}
	
	private void turnOffItemsPanel() {
		DOM.removeEventPreview(activeEP);
		itemsPanelVP.removeFromParent();
		//itemsSP.removeFromParent();
		itemsAP.clear();
	}

	
	private void addItemHTML(String text) {
		addItemHTML(text, false);
	}
	
	private void addItemHTML(String text, boolean selected) {
//		final HTML html = new HTML(text) {
//		};

		ItemHTML html = new ItemHTML(text); 
		
		html.setStyleName("item");
		html.setWidth("100%");
		
		if (selected) {
			html.addStyleName(STYLE_ITEMSLIST_SELECTED);
		}
		
		itemsAP.add(html);
		
		itemsAP.sinkEvents(Event.ONMOUSEOVER|Event.ONMOUSEOUT|Event.ONMOUSEUP);
		
//		html.addMouseListener(new MouseListenerAdapter(){
//			public void onMouseEnter(Widget sender) {
//				super.onMouseEnter(sender);
//				//RootPanel.get().add(new Label("enter"));
//				html.addStyleName(STYLE_ITEMSLIST_HOVER);
//			}
//			public void onMouseLeave(Widget sender) {
//				super.onMouseLeave(sender);
//				html.removeStyleName(STYLE_ITEMSLIST_HOVER);
//			}
//			public void onMouseUp(Widget sender, int x, int y) {
//				super.onMouseUp(sender, x, y);
//				AbsolutePanel vp = (AbsolutePanel)html.getParent();
//				selectedItemindex = vp.getWidgetIndex(html);
//				//Window.alert("wybrales pozycje " + index);
//				textBox.setText(html.getText());
//				turnOffItemsPanel();
//				
//				Planner.clearSelection();
//			}
//			
//		});
	}
	

	private void addUnselectableItemHTML(String text) {
		final HTML html = new HTML(text);

		html.setStyleName("unselectableItem");
		html.setWidth("100%");
		
		itemsAP.add(html);
	}
	
	
	public void addItem(String item) {
		addItem(item, item);
	}
	
	public void addItem(String item, String value) {
		items.add(item);
		values.add(value);
	}
	
	public void clear() {
		items.clear();
		values.clear();
	}
	
	public int getItemCount() {
		return items.size();
	}
	
	public String getItemText(int index) {
		return (String)items.get(index);
	}

	public String getValue(int index) {
		return (String)values.get(index);
	}

	private void setItemsPanelWidth(int w) {
		if (w < itemsPanelMinWidth) w = itemsPanelMinWidth;
		itemsPanelVP.setWidth(w+"px");
		itemsSP.setWidth(w + "px");
		itemsAP.setWidth(w + "px");
		bottomHTML.setWidth(w + "px");
	}
	
	private void setItemsPanelHeightImpl(int h) {
		if (h < itemsPanelMinHeight) h = itemsPanelMinHeight;
		
		if (h > itemsAP.getOffsetHeight()+ 26)
			h = itemsAP.getOffsetHeight() + 26;
		
		itemsPanelVP.setHeight(h + "px");
		itemsSP.setHeight(h-26 + "px");
	}
	
	public void setWidth(String width) {
		super.setWidth(width);
		textBox.setWidth(width);
	}

	

	private void setSelectedItemindex(int selectedItemindex) {
		this.selectedItemindex = selectedItemindex;
		if (selectedItemindex >-1 && selectedItemindex <items.size()) {
			textBox.setText((String)items.get(selectedItemindex));	
		}
		
	}
	
	public void setSelectedIndex(int selectedIndex) {
		setSelectedItemindex(selectedIndex);
	}

	public void setItemsPanelHeight(int itemsPanelHeight) {
		this.itemsPanelHeight = itemsPanelHeight;
	}

	
	private class ItemHTML extends HTML{
		public ItemHTML(String text) {
			super(text);
		}
		
		public void onBrowserEvent(Event event) {
			super.onBrowserEvent(event);
			
			switch (DOM.eventGetType(event)) {
			case Event.ONMOUSEOVER:
				this.addStyleName(STYLE_ITEMSLIST_HOVER);
				break;
				
			case Event.ONMOUSEOUT:
				this.removeStyleName(STYLE_ITEMSLIST_HOVER);
				break;
			case Event.ONMOUSEUP:
				AbsolutePanel vp = (AbsolutePanel)this.getParent();
				selectedItemindex = vp.getWidgetIndex(this);
				//Window.alert("wybrales pozycje " + index);
				textBox.setText(this.getText());
				turnOffItemsPanel();
				DOM.eventCancelBubble(event, true);
				
//				Planner.clearSelection();

				break;
				
			default:
				break;
			}
		}
	}
	
}
